#include "watch_bsp_aht21_driver.h"
#include "delay.h"
#include "elog.h"
static int8_t aht21_init(bsp_aht21_driver_t * instance)
{
    uint8_t status;
    /* wait */
    delay_ms(100);

    /* read status */
    if (0 != instance->psiic_driver_interface->pfread_bytes(&status, 1))
    {
        return -1;
    }

    /* check status */
    if (status && 0x18 != 0x18)
    {
		uint8_t tx_buffer[3] = {0xBE, 0x08, 0x00};
		if (0 != instance->psiic_driver_interface->pfwrite_bytes(tx_buffer, 3))
		{
			return -2;
		}
    }
    return 0;
}
static int8_t aht21_deinit(bsp_aht21_driver_t * instance)
{
    return 0;
}
static int8_t aht21_read_id (bsp_aht21_driver_t * instance,
							uint8_t *id)
{
    return 0;
}

static int8_t aht21_read_data(bsp_aht21_driver_t* instance,
                              float* ptemperature,
                              float* phumidity
                             )
{
    /* start measure */
    uint8_t tx_buffer[3] = {0xAC, 0x33, 0x00};
    if (0 != instance->psiic_driver_interface->pfwrite_bytes(tx_buffer, 3))
    {
        return -1;
    }
    delay_ms(100);
    uint8_t rx_buffer[6];
    if (0 != instance->psiic_driver_interface->pfread_bytes(rx_buffer, 6))
    {
        return -3;
    }
	
	/* measure finish*/
    if ((rx_buffer[0] & 0x80) == 0x00)
    {
        uint32_t data = 0;
        data = (((uint32_t)rx_buffer[3] >> 4) + ((uint32_t)rx_buffer[2] << 4) + ((uint32_t)rx_buffer[1] << 12));
        *phumidity = data * 100.0f / (1 << 20);

        data = ((((uint32_t)rx_buffer[3] & 0x0F) << 16) + ((uint32_t)rx_buffer[4] << 8) + (uint32_t)rx_buffer[5]);
        *ptemperature = data * 200.0f / (1 << 20) - 50;
    }
    return 0;
}

static int8_t aht21_deinst(bsp_aht21_driver_t * instance)
{
    if (instance != NULL)
    {   
       //iic driver deinit 
        if (instance->psiic_driver_interface !=NULL)
        {
            instance->psiic_driver_interface->pfinit          		 = NULL;
            instance->psiic_driver_interface->pfdeinit         		 = NULL;
            instance->psiic_driver_interface->pfread_register_bytes  = NULL;
            instance->psiic_driver_interface->pfwrite_register_bytes = NULL;
            instance->psiic_driver_interface->pfread_register_bytes  = NULL;
            instance->psiic_driver_interface->pfwrite_register_bytes = NULL;
        }

        //timebase driver deinit
        if (instance->pstimebase_interface != NULL)
        {
            instance->pstimebase_interface->pfget_tick_count   = NULL;
        }

        //aht21 deinit
        instance->pfdeinit            = NULL;
        instance->pfread_id           = NULL;
        instance->pfread_data         = NULL;
    }
    return 0;
}

int8_t aht21_inst(bsp_aht21_driver_t* aht21_instance,
                 iic_driver_interface_t* iic_instance,
                 timebase_interface_t* timebase_instance
                 )
{
    /* 1.instance not null */
    if (NULL == aht21_instance)
    {
        return -1;
    }

    if (NULL == iic_instance)
    {
        return -2;
    }

    if (NULL == timebase_instance)
    {
        return -3;
    }

    /*2. load iic driver */
    aht21_instance->psiic_driver_interface     = iic_instance;
    if (NULL == iic_instance->pfinit                    ||
        NULL == iic_instance->pfdeinit                  ||
        NULL == iic_instance->pfwrite_bytes             ||
        NULL == iic_instance->pfread_bytes              ||
        NULL == iic_instance->pfwrite_register_bytes    ||
        NULL == iic_instance->pfread_register_bytes     
        )
    {
        /* deint  iic driver */
        aht21_instance->psiic_driver_interface->pfdeinit();
        return -4;
    }

    /* 3.load timetbase */
    aht21_instance->pstimebase_interface       = timebase_instance;
    if (timebase_instance->pfget_tick_count == NULL)
    {
        /*deinit  timetbase */
        return -5;
    } 

    /* 4.aht21 initialization */
    aht21_instance->pfinit                     = aht21_init;
    aht21_instance->pfdeinit                   = aht21_deinit;
    aht21_instance->pfdeinst                   = aht21_deinst;
    aht21_instance->pfread_id                  = aht21_read_id;
    aht21_instance->pfread_data                = aht21_read_data;

    return 0;
}                            

